﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace QntPlatform.Strategy.Utility
{
   public class CalcFun
    {
        TAFun TA;

        /// <summary>计算仓位,通过可承受亏损能力
        /// 
        /// </summary>
        /// <param name="balance">账户余额</param>
        /// <param name="stopLoss"></param>
        /// <param name="nowPrice"></param>
        /// <param name="accountMaxLossRatio"></param>
        /// <param name="isLong"></param>
        /// <returns></returns>
        private decimal AmountCalc(decimal balance, decimal stopLoss, decimal nowPrice,decimal accountMaxLossRatio, bool isLong)
        {
            var longVal = isLong ? 1 : -1;
            var am = longVal * balance * accountMaxLossRatio / (nowPrice - stopLoss);
            return am;
        }

        /// <summary>计算止损，通过历史和atr
        /// 
        /// </summary>
        /// <param name="records"></param>
        /// <param name="isLong"></param>
        /// <returns></returns>
        private decimal StopLossCalcByATR(Record[] records, bool isLong)
        {
            var last7 = records.Skip(records.Length - 7); // Aggregate((p1, p2) =>(p1 == null || p1.Low > p2.Low)?p2:p1);
            var top = isLong ? last7.Min(p => p.Low) : last7.Max(p => p.High);
            var atr = (decimal)TA.ATR(records, 14).Last();
            var atrV = isLong ? -atr * 0.5m : atr * 0.5m;
            var stopLoss = top + atrV; //止损价
            return stopLoss;
        }

         public static decimal CalcProfitRate(decimal outPrice, decimal buyPrice, bool isLong = true)
        {
            return isLong ? outPrice / buyPrice - 1 : -(outPrice / buyPrice - 1);
        }

        /// <summary>
        ///  profitRate负值表示亏损率，正值表示盈利率
        /// </summary>
        /// <param name="profitRate"></param>
        /// <param name="buyPrice"></param>
        /// <param name="isLong"></param>
        /// <returns></returns>
        public static decimal CalcPriceByProfitRate(decimal profitRate, decimal buyPrice, bool isLong = true)
        {
            if (isLong)
                return buyPrice * (1 + profitRate);
            return buyPrice * (1 - profitRate);
        }
         public static   decimal CalcUnitProfit(decimal nowPrice, decimal buyPrice, bool isLong = true)
        {
            return isLong ? nowPrice - buyPrice : -(nowPrice - buyPrice);
        }
    }

   public class ConditionTrader
    {

        Func<decimal, bool> condition;
        public decimal ConditionPrice { get; set; }
        public decimal Amount { get; set; }
        public SideDirection Direction { get; set; }
        public bool IsEnd { get; set; }
        public bool Execute(decimal nowPrice) {
            if (IsEnd)
            {
                condition = p => p >= ConditionPrice;
                return true;
            }
            if (condition(nowPrice))
            {
                IsEnd = true;
                return true;
            }
            return false;
        }
    }
}
